package org.jeecg.modules.deepseek.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.IpUtils;
import org.jeecg.config.deepseek.ChatRequestBean;
import org.jeecg.config.shiro.IgnoreAuth;

import org.jeecg.modules.deepseek.pojo.ChatRequest;
import org.jeecg.modules.deepseek.pojo.ChatRequestExample;
import org.jeecg.modules.deepseek.pojo.Note;
import org.jeecg.modules.deepseek.service.DeepSeekService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.ResponseFormat;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

@RequestMapping("/deepseek1")
@RestController
@Slf4j
@CrossOrigin(origins = "*", methods = {RequestMethod.GET, RequestMethod.POST})
public class DeepSeekController {
    @Autowired
    private OpenAiChatModel deepseekChatModel;

//    @Autowired
//    ChatClient chatClient;

    @Autowired
    DeepSeekService deepSeekService;

    @Autowired
    ChatRequestBean chatRequestBean;


    @GetMapping(value = "/openai/functionCalling/v1")
    @IgnoreAuth
    public Map<String, String> functionCallingv1(@RequestParam(value = "message", defaultValue = "展示最新的OFFER?") String message, HttpServletRequest httpServletRequest) {
        return deepSeekService.functionCallingv1(message, IpUtils.getIpAddr(httpServletRequest));
    }


    @GetMapping(value = "/openai/generateStream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @IgnoreAuth
    public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "给我讲一个笑话") String message) {

        List<Message> messageList = Arrays.asList(new SystemMessage("请全部用简体中文回答"), new UserMessage(message));
        Prompt prompt = new Prompt(messageList);

        return deepseekChatModel.stream(prompt).map((r) -> r.getResult() != null && r.getResult().getOutput() != null && r.getResult().getOutput().getText() != null ? r.getResult().getOutput().getText() : "").filter(StringUtils::hasLength);
    }

    @GetMapping(value = "/openai/chat/v1")
    @IgnoreAuth
    public Map<String, String> generateStreamv1(@RequestParam(value = "message", defaultValue = "给我讲一个笑话") String message) {

        List<Message> messageList = Arrays.asList(new SystemMessage("你是无忧留学的AI助手，" +
                "帮助用户进行答疑解惑，请格式化输出内容到html的<body>标签中"), new UserMessage(message));

        Prompt prompt = new Prompt(messageList);
        ChatResponse response = this.deepseekChatModel.call(prompt); // Enable the function
        String content = response.getResult().getOutput().getText();
        HashMap<String, String> stringStringHashMap = new HashMap<>();
        stringStringHashMap.put("content", content);
        return stringStringHashMap;
    }
    @GetMapping(value = "functionCallingList")
    @IgnoreAuth
    public Result<List<String>> getFunctionCallingList(){

//        OpenAiApi.ChatCompletionRequest chatRequest = null;
//        try {
//            chatRequest = chatRequestBean.createChatRequestFunction();
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        List<OpenAiApi.FunctionTool> tools = chatRequest.tools();

        return Result.ok(List.of("您可以点击数据智能查询输入类似的内容","查询最新的offer","查询案例最多的顾问","查询美国的学校","哪个国家的offer最多","哪个老师的经验最丰富"));
    }

    @GetMapping(value = "/openai/functionCalling/v2")
    @IgnoreAuth
    public Map<String, String> functionCallingv2(@RequestParam(value = "message", defaultValue = "北大有多少个专业?") String message1) {
//        UserMessage userMessage = new UserMessage(message1);
        final String[] body1 = new String[1];
        Map<String, String> bodyMap = new HashMap<>();
        body1[0] = "系统出现BUG，请稍后再试";
        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手，请格式化输出内容到html的<body>标签中");
        ChatRequest.Message user = new ChatRequest.Message("user", message1);
        try {
            OpenAiApi.ChatCompletionRequest currentWeather = chatRequestBean.createChatRequestFunction1();
            List<OpenAiApi.FunctionTool> tools = currentWeather.tools();
            List<ChatRequest.Message> messages = new ArrayList<>(List.of(system, user));
            while (true) {
                ResponseEntity<OpenAiApi.ChatCompletion> chatCompletionChunkResponseEntity = ChatRequestExample.requestDeepSeekChat(tools, messages);
                OpenAiApi.ChatCompletion body = chatCompletionChunkResponseEntity.getBody();
                if (body == null) {
                    break; // 如果响应体为空，退出循环
                }
                List<OpenAiApi.ChatCompletion.Choice> choices = body.choices();
                if (choices.isEmpty()) {
                    break; // 如果 choices 为空，退出循环
                }
                OpenAiApi.ChatCompletion.Choice choice = choices.get(0);
                OpenAiApi.ChatCompletionMessage message = choice.message();
                List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls = message.toolCalls();
                if (toolCalls == null || toolCalls.isEmpty()) {
                    // toolCalls 为空，处理响应内容并退出循环
                    String content = message.content();
                    bodyMap.put("content", content);
                    break;
                } else {
//                    deepseekChatModel.
                    // toolCalls 不为空，处理工具调用并继续请求
                    Map<String, ToolCallback> functionCallbackRegister = chatRequestBean.ToosBeanFetcher();
                    messages.add(new ChatRequest.Message("assistant", toolCalls));
                    for (OpenAiApi.ChatCompletionMessage.ToolCall toolCall : toolCalls) {
                        ToolCallback functionCallback = functionCallbackRegister.get(toolCall.function().name());
                        if (functionCallback != null) {
                            String name = toolCall.function().name();
                            //TODO 后期这里需要优化，需要改造成通过注解的一个MAP拿到数据
                            String toolResponse = functionCallback.call(toolCall.function().arguments());
                            // 将工具调用的响应添加到消息列表中
                            if(name.equals("getTableSelector")){
                                ResponseEntity<OpenAiApi.ChatCompletion>
                                        chatCompletionChunkResponseEntity1 = ChatRequestExample.requestDeepSeekChat(null, List.of(
                                        system,
                                        user,
                                        new ChatRequest.Message("user", toolResponse)
                                ));
                                body1[0] = chatCompletionChunkResponseEntity1.getBody().choices().get(0).message().content();
                                bodyMap.put("content", body1[0]);
                                return bodyMap;
                            }else {
                                messages.add(new ChatRequest.Message("tool", toolResponse, toolCall.id()));
                            }

                        }
                    }
                    // 将 assistant 的消息添加到消息列表中（如果需要）
                }
            }
            return bodyMap;
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }


    @GetMapping(value = "/openai/functionCalling/v3")
    @IgnoreAuth
    public Map<String, String> functionCallingv3(@RequestParam(value = "message", defaultValue = "展示最新的OFFER?") String message) {
        UserMessage userMessage = new UserMessage(message);
        final String[] body1 = new String[1];
        Map<String, String> bodyMap = new HashMap<>();
        body1[0] = "系统出现BUG，请稍后再试";

        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手用户提问的内容，如果和函数无关，请不要调用函数，请格式化输出内容到html的<body>标签中");
        ChatRequest.Message user = new ChatRequest.Message("user", message);
        try {

            OpenAiApi.ChatCompletionRequest currentWeather =  chatRequestBean.createChatRequestFunction();
            List<OpenAiApi.FunctionTool> tools = currentWeather.tools();
            ResponseEntity<OpenAiApi.ChatCompletion> chatCompletionChunkResponseEntity = ChatRequestExample.requestDeepSeekChat(tools, List.of(system, user));
            Map<String, ToolCallback> functionCallbackRegister = chatRequestBean.ToosBeanFetcher();
            OpenAiApi.ChatCompletion body = chatCompletionChunkResponseEntity.getBody();
            if (body != null) {
                {
                    List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls = body.choices().get(0).message().toolCalls();
                    if (toolCalls == null || toolCalls.isEmpty()) {
                        body1[0] = body.choices().get(0).message().content();

                        bodyMap.put("content", body1[0]);
                        return bodyMap;
                    }
                    body.choices().forEach(choice -> {

                        List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls1 = choice.message().toolCalls();

                        //TODO 管理添加的功能，需要人工二次确认才可行
                        Iterator<OpenAiApi.ChatCompletionMessage.ToolCall> iterator = toolCalls1.iterator();
                        while (iterator.hasNext()) {
                            OpenAiApi.ChatCompletionMessage.ToolCall toolCall = iterator.next(); // 获取当前元素
                            FunctionCallback functionCallback = functionCallbackRegister.get(toolCall.function().name());
                            String call = functionCallback.call(toolCall.function().arguments());
                            // 如果不是最后一个元素，继续迭代
                            if (iterator.hasNext()) {

                            } else {
                                // 如果是最后一个元素，执行额外的逻辑
                                ResponseEntity<OpenAiApi.ChatCompletion>
                                        chatCompletionChunkResponseEntity1 = ChatRequestExample.requestDeepSeekChat(null, List.of(
                                        system,
                                        user,
                                        new ChatRequest.Message("user", call)
                                ));
                                body1[0] = chatCompletionChunkResponseEntity1.getBody().choices().get(0).message().content();
                                bodyMap.put("content", body1[0]);
                            }
                        }
                    });
                }
            }
            return bodyMap;
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
//    @PostMapping("/save")
//    @IgnoreAuth
//    public ResponseEntity<String> saveNote(@RequestBody Note note)  {
//        ChatRequest.Message system = new ChatRequest.Message("system", "你是公司内部的AI助手，请格式化输出内容到html的<body>标签中");
//        ChatRequest.Message user = new ChatRequest.Message("user", note.getContent());
//        OpenAiApi.ChatCompletionRequest currentWeather = chatRequestBean.createChatRequestFunctionNote();
//        Map<String, ToolCallback> functionCallbackRegister = chatRequestBean.ToosBeanFetcher();
//        List<OpenAiApi.FunctionTool> tools = currentWeather.tools();
//        List<ChatRequest.Message> messages = new ArrayList<>(List.of(system, user));
//        ResponseEntity<OpenAiApi.ChatCompletion> chatCompletionChunkResponseEntity = ChatRequestExample.requestDeepSeekChat(tools, messages);
//        OpenAiApi.ChatCompletion body = chatCompletionChunkResponseEntity.getBody();
//        if (body == null) {
//            return ResponseEntity.ofNullable("失败");
//        }
//        List<OpenAiApi.ChatCompletion.Choice> choices = body.choices();
//        if (choices.isEmpty()) {
//            return ResponseEntity.ofNullable("失败");
//        }
//        List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls = body.choices().get(0).message().toolCalls();
//        if (toolCalls == null || toolCalls.isEmpty()) {
//            return ResponseEntity.ofNullable("失败");
//        }
//        body.choices().forEach(choice -> {
//
//            List<OpenAiApi.ChatCompletionMessage.ToolCall> toolCalls1 = choice.message().toolCalls();
//
//            //TODO 管理添加的功能，需要人工二次确认才可行
//            Iterator<OpenAiApi.ChatCompletionMessage.ToolCall> iterator = toolCalls1.iterator();
//            while (iterator.hasNext()) {
//                OpenAiApi.ChatCompletionMessage.ToolCall toolCall = iterator.next(); // 获取当前元素
//                FunctionCallback functionCallback = functionCallbackRegister.get(toolCall.function().name());
//                String call = functionCallback.call(toolCall.function().arguments());
//                log.info(call);
//                // 如果不是最后一个元素，继续迭代
//                if (iterator.hasNext()) {
//
//                } else {
//                    // 如果是最后一个元素，执行额外的逻辑
//                    ResponseEntity<OpenAiApi.ChatCompletion>
//                            chatCompletionChunkResponseEntity1 = ChatRequestExample.requestDeepSeekChat(null, List.of(
//                            system,
//                            user,
//                            new ChatRequest.Message("user", call)
//                    ));
//
//                }
//            }
//        });
//        return ResponseEntity.ok("Note saved successfully");
//    }
}
